package com.sun.tv;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;


import android.content.Context;

import com.sun.tv.AdConfig.ResType;
import com.tools.MyLog;
import com.tools.SysInterfacePhone;

public class IMochaSharedPreferences {
	private static final String time = "time";
	private static final String name = "name";
	private static final String url = "url";
	private static final String strUseSize = "useSize";
	private static final String ad = "ad";
	private static final String AdConfigName = "cfg.bin";

	public IMochaSharedPreferences() {
	}

	/***********************************************************
	 * @author sun.huang MSN:jxhuanghua@yahoo.com.cn
	 * @version time：2011-6-2 上午10:43:39
	 * @return
	 * @TODO 取得资源配置文件
	 ***********************************************************/
	public JSONObject getJson(Context Context) {
		if (Context == null) {
			MyLog.e("Context is null");
			return null;
		}
		byte[] bytes = SysInterfacePhone.invoker().loadFileFromSDCard(Context,
				SysInterfacePhone.invoker().getPath(Context), AdConfigName);
		try {// 文件正常
			adJson = new JSONObject(new String(bytes));
			adJsonArray = adJson.getJSONArray(ad);
		} catch (Exception e) {// 文件内容为空或非JSON格式。文件内容有问题。
			bytes = SysInterfacePhone.invoker().loadFileFromSDCard(Context,
					SysInterfacePhone.invoker().getPath(Context), "temp.bin");// 如果原文件不存在。则加载临时文件。
			try {
				adJson = new JSONObject(new String(bytes));
				adJsonArray = adJson.getJSONArray(ad);
			} catch (Exception e2) {// 如js
				SysInterfacePhone.invoker().delFolder(
						SysInterfacePhone.invoker().getPath(Context));
				adJson = new JSONObject();
				try {
					adJson.put(strUseSize, 0l);
					adJsonArray = new JSONArray();
					adJson.put(ad, adJsonArray);
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}
		}
		return adJson;
	}

	/***********************************************************
	 * @author sun.huang MSN:jxhuanghua@yahoo.com.cn
	 * @version time：2011-6-2 上午10:44:50
	 * @return
	 * @TODO 本地是否有广告资源
	 ***********************************************************/
	boolean hasAd(String key, AdConfig config) {
		WeakReference<TVAdView> adViewinteReference = TVAdManage.admanage.getAdView(key);
		if (adViewinteReference == null) {
			MyLog.e("adViewinteReference is null");
			return false;
		}
		TVAdView adView = (TVAdView) adViewinteReference.get();
		if (adView == null) {
			MyLog.e("adView is null");
			return false;
		}
		Context context = adView.contextWeakReference.get();
		if (context == null) {
			MyLog.e("Context is null");
			return false;
		}

		getJson(context);
		try {
			for (int i = 0; i < adJsonArray.length(); i++) {
				JSONObject json;
				json = adJsonArray.getJSONObject(i);
				String tempurl = json.getString(url);
				// 如果二個URL相同 且文件存在hdtindex.html
				if (tempurl.equals(config.getResUrl())
						&& SysInterfacePhone.invoker().fileExists(
								SysInterfacePhone.invoker().getPath(context),
								json.getString(name))) {
					// adView.onEvent(IMochaEventCode.hasRes);
					return true;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			// adView.onEvent(IMochaEventCode.noHasRes);
			return false;
		}
		// adView.onEvent(IMochaEventCode.noHasRes);
		return false;
	}

	/***********************************************************
	 * @author sun.huang MSN:jxhuanghua@yahoo.com.cn
	 * @version time：2011-6-1 上午11:15:55
	 * @return
	 * @TODO期 计算剩余可用空间 返回值为字节.
	 ***********************************************************/
	public long getFreeDouseMemory(Context Context) {

		if (Context == null) {
			MyLog.e("Context is null");
			return -1;
		}
		getJson(Context);
		/* 总缓存空间 */
		long totalMemory = getMemory();
		try {
			return totalMemory - adJson.getLong(strUseSize);
		} catch (JSONException e) {
			e.printStackTrace();
			return -1;
		}
	}

	/***********************************************************
	 * @author sun.huang MSN:jxhuanghua@yahoo.com.cn
	 * @version time：2011-6-2 上午10:03:42
	 * @param bytes
	 * @return 1-6 2201-2204 330263
	 * @TODO 保存广告
	 ***********************************************************/
	boolean saveAd(String key, AdConfig config) {
		// 可用空间
		WeakReference<TVAdView> adViewinteReference = TVAdManage.admanage.adViewWindowMap
				.get(key);
		if (adViewinteReference == null) {
			MyLog.e("adViewinteReference is null");
			return false;
		}
		TVAdView adView = (TVAdView) adViewinteReference.get();
		if (adView == null) {
			MyLog.e("adView is null");
			return false;
		}
		Context context = adView.contextWeakReference.get();
		if (context == null) {
			MyLog.e("Context is null");
			return false;
		}
		String outputDirectory = SysInterfacePhone.invoker().getPath(context);// 有SD卡："/android/android/com/.image"
		long freeDouseSize = getFreeDouseMemory(context);
		long useSize = config.bytes.length;
//		if (config.resType == ResType.Html) {
//			try {
//				ByteArrayInputStream inputStream = new ByteArrayInputStream(
//						config.bytes);
//				useSize = unzip(inputStream,
//						outputDirectory + "/" + config.getResName(),
//						adView.getContext(), config);
//				/*------ ran.huang 2012-12-18 上午10:01:55 add start ------*/
//				// 解压html.zip文件后判断其类型（Localimage,Localhtml,html）
//				config.getHtmlType(Context);
//				/*------ ran.huang 2012-12-18 上午10:02:03 add end ------*/
//			} catch (Exception e) {
//				SysInterfacePhone.invoker().deleteFile(adView.getContext(),
//						outputDirectory + "/" + config.getResName());
//				MyLog.e(e);
//				return false;
//			}// 解压zip文件
//		}
		boolean b = saveAd(context, config, freeDouseSize, useSize);
		if(!b)
			SysInterfacePhone.invoker().deleteFile(adView.getContext(),
					outputDirectory + "/" + config.getResName());
		return b;
		
	}

	boolean saveAd(Context Context, AdConfig config, long freeDouseSize,
			long folderSize) {
		if (folderSize < freeDouseSize) {// 如果下载资源<可用空间
			boolean b = false;
			try {
				// 解压html.zip文件后，判断解压目录里是否存在需要的hdtmobileindex.html文件
				if (config.resType == ResType.Html || config.resType == ResType.LocalHtml) {// 如果存储的是ZIP解压后的目录
					String pathName = SysInterfacePhone.invoker().getPath(
							Context);
					String fileString = SysInterfacePhone.invoker()
							.getZipMainClassFilePath(
									pathName + "/" + config.getResName(),
									config.resType.getMainClassName());
					if (fileString == null) {
						b = false;
					} else {
						b = true;
					}
				} else if (config.resType == ResType.Localimage) {
					String pathName = SysInterfacePhone.invoker().getPath(
							Context);
					String[] imagepath = new File(pathName + "/"
							+ config.getResName() + "/res").list();
					if (imagepath == null) {
						b = false;
					} else {
						b = true;
					}
				} else if (config.resType == ResType.Image) {// 如果是IMAGE类型资源则直接添加到缓存
					b = saveRes(Context, config);
				}
				return b;
			} catch (Exception e) {
				e.printStackTrace();
				return false;
			} finally {
				if (b) {
					saveJsonList(Context, config, folderSize);
				} else {
					SysInterfacePhone.invoker().deleteFile(Context,
							config.getResName());
				}
				config.bytes = null;
			}

		} else {// 下载资源 > 可用空间
			try {
				int index = 0;
				long useSize = 0;
				if(adJsonArray.length()<=0)
				return false;
				for (int i = 0; i < adJsonArray.length(); i++) {
					JSONObject json = adJsonArray.getJSONObject(i);
					// 当前可用广告大小
					long size = json.getLong(strUseSize);
					String name = json.getString(IMochaSharedPreferences.name);
					SysInterfacePhone.invoker().deleteFile(
							Context,
							SysInterfacePhone.invoker().getPath(Context) + "/"
									+ name);
					// 可用空间增加 262152
					freeDouseSize += size;
					if (freeDouseSize > folderSize) {
						// 可用空间大于文件（夹）的大小
						index = i + 1;
						break;
					}
				}
				JSONArray tempArray = new JSONArray();
				for (int j = index; j < adJsonArray.length(); j++) {
					JSONObject json = adJsonArray.getJSONObject(j);
					long size = json.getLong(strUseSize);
					useSize += size;
					tempArray.put(json);
				}
				adJson.remove(ad);
				adJson.put(ad, tempArray);
				adJson.put(strUseSize, useSize);
				return saveAd(Context, config, freeDouseSize, folderSize);

			} catch (JSONException e) {
				e.printStackTrace();
				return false;
			}
		}
	}

	/***********************************************************
	 * @author sun.huang MSN:jxhuanghua@yahoo.com.cn
	 * @version time：2011-7-12 上午09:39:56
	 * @param context
	 * @param config
	 * @return 保存配置文件与资源文件
	 * @TODO
	 ***********************************************************/
	private boolean saveRes(Context context, AdConfig config) {
		try {
			return SysInterfacePhone.invoker().saveFile(context,
					SysInterfacePhone.invoker().getPath(context),
					config.getResName(), config.bytes);

			// if (SysInterfacePhone.invoker().isSD()) {
			// // 保存资源
			// return SysInterfacePhone.invoker().saveFile(context,
			// SysInterfacePhone.invoker().getPath(context),
			// config.getResName(), config.bytes);
			// } else {// 保存资源
			// return
			// SysInterfacePhone.invoker().saveFileToAPK(context,SysInterfacePhone.invoker().getPath(context),
			// config.getResName(),Context.MODE_WORLD_READABLE +
			// Context.MODE_WORLD_WRITEABLE, config.bytes);
			// }
		} catch (Exception e) {
			return false;
		}

	}

	/***********************************************************
	 * @author sun.huang MSN:jxhuanghua@yahoo.com.cn
	 * @version time：2011-10-13 下午05:36:45
	 * @param context
	 * @param config
	 * @return
	 * @TODO 保存配置文件
	 ***********************************************************/
	private boolean saveJsonList(Context context, AdConfig config,
			long folderSize) {
		JSONObject json = new JSONObject();
		try {
			json.put(name, config.getResName());
			json.put(time, System.currentTimeMillis());
			json.put(strUseSize, folderSize);
			json.put(url, config.getResUrl());
			adJsonArray = adJson.getJSONArray(ad);
			adJsonArray.put(json);
			adJson.put(ad, adJsonArray);
			long useSize = adJson.getLong(strUseSize);
			adJson.put(strUseSize, useSize + folderSize);
		} catch (JSONException e) {
			e.printStackTrace();
			return false;
		}
		// if (SysInterfacePhone.invoker().isSD()) {
		// 保存配置
		return SysInterfacePhone.invoker().saveFile(context,
				SysInterfacePhone.invoker().getPath(context), AdConfigName,
				adJson.toString().getBytes());

		// } else {
		// // 保存配置
		// return SysInterfacePhone.invoker().saveFileToAPK(context,
		// SysInterfacePhone.invoker().getPath(context),AdConfigName,
		// Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE,
		// adJson.toString().getBytes());
		// }

	}

	/***********************************************************
	 * @author sun.huang MSN:jxhuanghua@yahoo.com.cn
	 * @version time：2011-6-3 上午10:31:00
	 * @param context
	 * @return
	 * @TODO 删除超时（30天）的文件
	 ***********************************************************/
	boolean deletTimeOutRes(Context Context) {
		getJson(Context);
		long useSize = 0;
		try {
			JSONArray tempArray = new JSONArray();
			for (int i = 0; i < adJsonArray.length(); i++) {
				JSONObject json = adJsonArray.getJSONObject(i);
				double useTime = System.currentTimeMillis()
						- json.getLong(time);

				double days = useTime / 1000.0 / 60.0 / 60.0 / 24.0;// 计算文件保存的天数
				// 如果保存期过了三十天则进行删除操作没有超过三十天的文件继续保存
				if (days > 30) {
					String name = json.getString(IMochaSharedPreferences.name);
					SysInterfacePhone.invoker().deleteFile(
							Context,
							SysInterfacePhone.invoker().getPath(Context) + "/"
									+ name);
				} else {
					long size = json.getLong(strUseSize);
					useSize += size;
					tempArray.put(json);
				}
			}
			adJson.put(ad, tempArray);//
			adJson.put(strUseSize, useSize);
			// if (SysInterfacePhone.invoker().isSD()) {
			// // 保存配置
			SysInterfacePhone.invoker().saveFile(Context,
					SysInterfacePhone.invoker().getPath(Context),
					AdConfigName, adJson.toString().getBytes());
			// } else {
			// 保存配置
			// SysInterfacePhone.invoker().saveFileToAPK(Context,
			// SysInterfacePhone.invoker().getPath(Context),AdConfigName,
			// Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE,
			// adJson.toString().getBytes());
			// }
			adJsonArray = null;
			adJson = null;

		} catch (Exception e) {
			e.printStackTrace();
			SysInterfacePhone.invoker().delAllFile(
					SysInterfacePhone.invoker().getPath(Context));
		}
		return true;
	}

	/***********************************************************
	 * @author sun.huang MSN:jxhuanghua@yahoo.com.cn
	 * @version time：2011-7-12 上午09:39:12
	 * @param contentSize
	 * @return 比较文件大小与最大缓存大小
	 * @TODO
	 ***********************************************************/
	boolean isEnoughMemory(long contentSize) {
		return contentSize < getMemory();
	}

	/***********************************************************
	 * @author sun.huang MSN:jxhuanghua@yahoo.com.cn
	 * @version time：2011-7-12 上午09:38:28
	 * @return
	 * @TODO 取得缓存大小上限 返回值为byte
	 ***********************************************************/
	public long getMemory() {
		double total = SysInterfacePhone.invoker().isSD() ? memory2 : memory1;
		return (long) (total * (double) 1024);
	}

	public void deletAllRes(Context context) {
		SysInterfacePhone.invoker().delAllFile(
				SysInterfacePhone.invoker().getPath(context));
	}

	/***********************************************************
	 * @author sun.huang MSN:jxhuanghua@yahoo.com.cn
	 * @version time：2011-7-12 上午09:35:03
	 * @param memory1
	 *            单位为KB 单应用缓存
	 * @TODO
	 ***********************************************************/
	static void setTotalMemory(double memory1) {
		if (memory1 <= 1 * 1024 && memory1 > 0) {
			IMochaSharedPreferences.memory1 = memory1;
		}
	}

	/***********************************************************
	 * @author sun.huang MSN:jxhuanghua@yahoo.com.cn
	 * @version time：2011-10-8 下午03:38:31
	 * @param zipInputStream
	 * @param outputDirectory
	 * @throws Exception
	 * @TODO 解压zip文件
	 ***********************************************************/
	private long unzip(InputStream zipInputStream, String outputDirectory,
			Context context, AdConfig config) throws Exception {
		File adFile = new File(outputDirectory);
		if (!adFile.exists()) {
			adFile.mkdirs();
		}
		ZipInputStream in = new ZipInputStream(zipInputStream);
		ZipEntry z;
		String name = "";
		int counter = 0;
		long folderSize = 0;
		// boolean b = false;;
		while ((z = in.getNextEntry()) != null) {
			name = z.getName();
			folderSize += z.getSize();
			if (z.isDirectory()) {
				// b = true;
				name = name.substring(0, name.length() - 1);
				File folder = new File(outputDirectory + File.separator + name);
				folder.mkdirs();
				counter++;
			} else {
				// b = true;
				File file = new File(outputDirectory + File.separator + name);
				MyLog.d("filedir " + outputDirectory + File.separator + name);
				file.createNewFile();
				// get the output stream of the file
				FileOutputStream out = new FileOutputStream(file);
				int ch;
				byte[] buffer = new byte[1024];
				// read (ch) bytes into buffer
				while ((ch = in.read(buffer)) != -1) {
					out.write(buffer, 0, ch);
					out.flush();
				}
				out.close();
			}
		}
		in.close();
		return folderSize;

	}

	/***********************************************************
	 * @author sun.huang MSN:jxhuanghua@yahoo.com.cn
	 * @version time：2011-10-28 上午11:15:10
	 * @param from
	 *            起点目录
	 * @param to
	 *            目标路径
	 * @throws Exception
	 * @TODO 移动文件（夹）
	 ***********************************************************/
	public static void fileMove(String from, String to) throws Exception {
		try {
			File dir = new File(from);
			// 文件一览
			File[] files = dir.listFiles();
			if (files == null)
				return;
			// 目标
			File moveDir = new File(to);
			if (!moveDir.exists()) {
				moveDir.mkdirs();
			}
			// 文件移动
			for (int i = 0; i < files.length; i++) {
				if (files[i].isDirectory()) {
					fileMove(files[i].getPath(), to + "\\" + files[i].getName());
					// 成功，删除原文件
					files[i].delete();
				}
				File moveFile = new File(moveDir.getPath() + "\\"
						+ files[i].getName());
				// 目标文件夹下存在的话，删除
				if (moveFile.exists()) {
					moveFile.delete();
				}
				files[i].renameTo(moveFile);
			}
			dir.delete();
		} catch (Exception e) {
			throw e;
		}
	}

	/** 单应用缓存 */
	private static double memory1 = 1 * 1024;
	/** 共享缓存 */
	private static double memory2 = 5 * 1024;

	private JSONObject adJson = null; // 广告缓存配置文件（由二个JSON对像组成：adJsonArray+ad(JSONObject类型)）
	private JSONArray adJsonArray = null; // 广告数组（广告列表）
}
